from typing import Dict, List
import numpy as np
from datetime import datetime

class PositionLimiter:
    """头寸限额管理"""
    
    def __init__(self, config: Dict):
        self.single_symbol_limit = config.get('single_symbol_limit', 0.3)  # 单品种持仓限额
        self.sector_limits = config.get('sector_limits', {})  # 行业持仓限额
        self.total_assets_limit = config.get('total_assets_limit', 1.5)  # 总资产杠杆限制
        self.position_history = {}  # 持仓历史记录
        
    def check_order(self, order: Dict, portfolio: Dict) -> bool:
        """检查订单是否符合头寸限制"""
        symbol = order['symbol']
        quantity = order['quantity']
        price = order['price']
        
        # 实时计算潜在持仓
        potential_position = self._calculate_potential_position(symbol, quantity, portfolio)
        
        checks = [
            self._check_single_symbol(symbol, potential_position, portfolio),
            self._check_sector_exposure(symbol, potential_position, portfolio),
            self._check_leverage(potential_position, portfolio)
        ]
        
        return all(checks)
    
    def _calculate_potential_position(self, symbol: str, quantity: int, portfolio: Dict) -> Dict:
        """计算潜在持仓"""
        current = portfolio['positions'].get(symbol, {'quantity': 0, 'market_value': 0})
        new_quantity = current['quantity'] + quantity
        return {
            'quantity': new_quantity,
            'market_value': new_quantity * portfolio['prices'].get(symbol, 0)
        }
    
    def _check_single_symbol(self, symbol: str, position: Dict, portfolio: Dict) -> bool:
        """检查单品种限额"""
        max_value = portfolio['total_assets'] * self.single_symbol_limit
        return position['market_value'] <= max_value
    
    def _check_sector_exposure(self, symbol: str, position: Dict, portfolio: Dict) -> bool:
        """检查行业暴露"""
        sector = self._get_symbol_sector(symbol)
        if sector not in self.sector_limits:
            return True
            
        sector_value = sum(
            p['market_value'] for s,p in portfolio['positions'].items() 
            if self._get_symbol_sector(s) == sector
        ) + position['market_value']
        
        return sector_value <= (portfolio['total_assets'] * self.sector_limits[sector])
    
    def _check_leverage(self, position: Dict, portfolio: Dict) -> bool:
        """检查杠杆率"""
        total_exposure = sum(p['market_value'] for p in portfolio['positions'].values()) \
                        + position['market_value']
        return total_exposure <= (portfolio['total_assets'] * self.total_assets_limit)
    
    def _get_symbol_sector(self, symbol: str) -> str:
        """获取品种所属行业（需对接数据服务）"""
        # 此处应调用数据智能体的接口
        return 'technology'  # 示例返回值